package com.ocean.web.util.file;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

/**
 * 文件名称读取工具类（支持本地路径、FTP路径、HTTP URL等）
 */
public class FileNameExtractor {

    /**
     * 从文件地址中提取文件名（通用方法）
     * 支持场景：
     * 1. 本地路径：D:/test/文件1.txt、/home/user/文档.pdf、C:\Users\test\image.png
     * 2. FTP路径：ftp://192.168.1.100/data/upload/large.zip、/data/upload/中文文件.docx
     * 3. HTTP/HTTPS URL：https://example.com/files/xxx.exe?id=123、http://xxx.com/下载.pdf
     *
     * @param fileAddress 文件地址（本地路径、FTP路径、HTTP URL等）
     * @return 提取到的文件名（含扩展名），提取失败返回null
     */
    public static String extractFileName(String fileAddress) {
        if (fileAddress == null || fileAddress.trim().isEmpty()) {
            return null;
        }

        // 1. 处理URL编码（如中文文件名被编码为%E4%B8%AD%E6%96%87.txt）
        String decodedAddress = decodeUrl(fileAddress);
        if (decodedAddress == null) {
            decodedAddress = fileAddress; // 解码失败则使用原始地址
        }

        // 2. 统一路径分隔符（将 \ 转为 /，适配Windows系统）
        String unifiedAddress = decodedAddress.replace("\\", "/");

        // 3. 移除URL中的查询参数（如 ?id=123、#fragment）
        String cleanAddress = removeUrlParameters(unifiedAddress);

        // 4. 提取最后一个 / 后的字符串作为文件名
        int lastSlashIndex = cleanAddress.lastIndexOf("/");
        if (lastSlashIndex == -1) {
            // 没有路径分隔符，直接返回整个字符串（如 "test.txt"）
            return cleanAddress.trim();
        }

        // 5. 截取文件名（排除路径部分）
        String fileName = cleanAddress.substring(lastSlashIndex + 1).trim();

        // 6. 处理特殊情况（如路径以 / 结尾，返回空时修正）
        return fileName.isEmpty() ? null : fileName;
    }

    /**
     * 解码URL编码的地址（处理中文/特殊字符编码）
     */
    private static String decodeUrl(String address) {
        try {
            // 先尝试直接解码（处理普通编码场景）
            return URLDecoder.decode(address, StandardCharsets.UTF_8.name());
        } catch (IllegalArgumentException e) {
            // 若直接解码失败，尝试通过URI解析（处理复杂URL场景）
            try {
                URI uri = new URI(address);
                return URLDecoder.decode(uri.getPath(), StandardCharsets.UTF_8.name());
            } catch (URISyntaxException | IllegalArgumentException | UnsupportedEncodingException ex) {
                // 所有解码方式失败，返回null
                return null;
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 移除URL中的查询参数和锚点（如 ?id=123、#part1）
     */
    private static String removeUrlParameters(String address) {
        // 移除 ? 后的查询参数
        int queryIndex = address.indexOf("?");
        if (queryIndex != -1) {
            address = address.substring(0, queryIndex);
        }
        // 移除 # 后的锚点
        int anchorIndex = address.indexOf("#");
        if (anchorIndex != -1) {
            address = address.substring(0, anchorIndex);
        }
        return address;
    }

    // ------------------------------ 测试方法 ------------------------------
    public static void main(String[] args) {
        // 测试各种场景
        String[] testAddresses = {
                "D:/test/文件1.txt", // 本地Windows路径（中文）
                "/home/user/文档.pdf", // 本地Linux路径
                "C:\\Users\\test\\image.png", // 本地Windows路径（反斜杠）
                "ftp://192.168.1.100/data/upload/large.zip", // FTP路径
                "/data/upload/中文文件.docx", // FTP相对路径（中文）
                "https://example.com/files/xxx.exe?id=123&type=file", // HTTP URL带参数
                "http://xxx.com/下载.pdf", // HTTP URL（中文）
                "https://example.com/path/to/file%E4%B8%AD%E6%96%87.txt", // URL编码中文
                "test.csv", // 无路径直接文件名
                "ftp://user:pass@ftp.server.com/folder/subfolder/archive.rar", // FTP带账号密码
                "https://example.com/long/path/with/many/slashes/file.jpg#part1" // 带锚点
        };

        for (String address : testAddresses) {
            String fileName = extractFileName(address);
            System.out.printf("地址：%s%n文件名：%s%n%s%n",
                    address, fileName, "----------------------------------------");
        }
    }
}